package com.topscomm.meet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.topscomm.basic.exception.ServiceException;
import com.topscomm.mis.MisController;
import com.topscomm.tap.constant.TapHttpErrorCode;
import com.topscomm.tap.constant.TapHttpStatus;
import org.springframework.web.bind.annotation.*;

import com.topscomm.app.pojo.AppPageEntity;
import com.topscomm.app.service.IAppPageService;
import com.topscomm.app.service.IAppPageTabService;
import com.topscomm.cbo.pojo.CboApprovalNodeInsEntity;
import com.topscomm.cbo.service.ICboApprovalNodeInsService;
import com.topscomm.cbo.service.ICboApprovalNodeService;
import com.topscomm.cbo.service.ICboAttachmentService;
import com.topscomm.cbo.service.impl.CboAttachmentService;
import com.topscomm.pub.util.BaseUtil;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.vo.ResponseResult;
import com.topscomm.tap.TapController;

public class MeetController<T extends MeetEntity, TService extends IMeetService<T, ?>>
        extends MisController<T, TService> implements IMeetController<T, TService> {
    @Resource(name = "appPageService")
    protected IAppPageService appPageService;
    @Resource(name = "cboApprovalNodeInsService")
    ICboApprovalNodeInsService cboApprovalNodeInsService;
    @Resource(name = "appPageTabService")
    protected IAppPageTabService appPageTabService;

    /**
     * 手机提交审批
     *
     * @param paraMap
     * @return
     * @description:
     * @author: donghang
     * @date: 2020年11月24日下午5:00:08
     * @modify:
     */
    @RequestMapping(value = "/mobileSubmit", method = {RequestMethod.POST, RequestMethod.PUT})
    public ResponseResult<Object> approvalSubmit(@RequestBody(required = false) Map<String, Object> paraMap) {
        try {
            ResponseResult<Object> responseData = this.insert(paraMap);
            if (responseData.isSuccess()) { // 提交审批
                Map<String, Object> responseMap = (Map<String, Object>) responseData.getResult();
                ResponseResult<Object> submitData = this.submit(responseMap);
                if (submitData.isSuccess() == false) {// 删除单子
                    this.service.deleteById(ConvertUtil.convertToString(responseMap.get("id")));
                }
                return submitData;
            } else {
                return responseData;
            }
        } catch (Exception ex) {
            return handleControllerException(ex);
        }
    }

    /**
     * 审批详情(单表)
     *
     * @param paraMap
     * @return
     * @throws SQLException
     * @throws IOException
     */
    @GetMapping(value = "/loadMobilePageInfo")
    public ResponseResult<Object> loadMobilePageInfo(@RequestParam(required = false) Map<String, Object> paraMap)
            throws SQLException, IOException {
        paraMap = BaseUtil.decodeSecureMap(paraMap);
        String pageCode = this.service.getDao().getTableName();
        Map<String, Object> myDadaMap = new HashMap<>();
        // 查询页面配置的sql语句
        StringBufferProxy sqlForAppPage = new StringBufferProxy();
        StringBufferProxy sqlForAppPageTab = new StringBufferProxy();
        sqlForAppPage.appendSingle("code='{0}' and enabled=1", pageCode);
        // 获取页面信息
        AppPageEntity page = appPageService.queryObjectByWhere(sqlForAppPage.toString());
        // 获取tab信息
        sqlForAppPageTab.appendSingle("pageid='{0}' and enabled=1", page.getId());
        List<Map<String, Object>> appPageTabList = appPageTabService.queryMapByWhere(sqlForAppPageTab.toString());
        // 获取主Tab(list中只有一个mainTab)
        List<Map<String, Object>> listMain = appPageTabList.stream()
                .filter(b -> "mainTableList".equals(ConvertUtil.convertToString(b.get("code"))))
                .collect(Collectors.toList());
        // 获取节点信息
        Map<String, Object> mainListData1 = this.service.queryMapById(paraMap.get("id").toString());// 主表信息

        CboApprovalNodeInsEntity queryById = cboApprovalNodeInsService
                .queryObjectByWhere("flowid = '" + mainListData1.get("flowid").toString() + "'");
        Map<String, Object> mainTab = listMain.get(0);
        // 如果此页面有一个tab则只需要处理主表数据
        if (appPageTabList.size() <= 1) {
            // 取数据
            Map<String, Object> mainListData = this.service.queryMapById(paraMap.get("id").toString());
            // 将取出的详细数据放入
            List<Map<String, Object>> mainList = new ArrayList<>();
            mainList.add(mainListData);
            // 其他主表数据
            mainListExtraData(paraMap, mainListData);
            // 塞入数据（数据的key约定为“表名+‘List’”）
            myDadaMap.put("mainList", mainList);
            // 获取页面（约定：app管理页面配置中的页面编码对应controller表名）
            appPageService.getPageInfo(this.service.getDao().getTableName(), myDadaMap);
            return ResponseResult.ok(myDadaMap);
        } else {
            // 处理多tab逻辑（约定：1.mainList为单据信息 2.其他Tab信息：扩展1字段：查询此tab的controller
            // 2.扩展2字段：主tab中的字段 3.扩展3字段：此tab中的字段）
            // 主表数据
            Map<String, Object> mainListData = this.service.queryMapById(paraMap.get("id").toString());
            mainListExtraData(paraMap, mainListData);
            // 将取出的详细数据放入
            List<Map<String, Object>> mainList = new ArrayList<>();
            mainList.add(mainListData);
            // 塞入主表数据数据（数据的key约定为“表名+‘List’”）
            myDadaMap.put("mainList", mainList);
            // 查询其他tab数据
            for (Map<String, Object> tabItem : appPageTabList) {
                if (!"mainList".equals(ConvertUtil.convertToString(tabItem.get("code")))) {
                    // 子表action
                    MeetController basicSubAction = (MeetController) SpringUtil
                            .getBean(ConvertUtil.convertToString(tabItem.get("extendfield1")));
                    // 查询子表数据的sql语句
                    StringBufferProxy sqlForSub = new StringBufferProxy();
                    // 主tab字段名称
                    String mainTabFieldStr = ConvertUtil.convertToString(tabItem.get("extendfield2"));
                    // 此tab字段名称
                    String subTabFieldStr = ConvertUtil.convertToString(tabItem.get("extendfield3"));
                    // app模板页面id
                    String tabTemplateId = ConvertUtil.convertToString(tabItem.get("extendfield4"));
                    // 拼装此tab需要的sql
                    sqlForSub.appendSingle("{0} = '{1}'", subTabFieldStr,
                            ConvertUtil.convertToString(mainListData.get(mainTabFieldStr)));
                    // 查询子表数据
                    List<Map<String, Object>> subList = basicSubAction.service.queryMapByWhere(sqlForSub.toString());
                    // 将取出的详细数据放入
                    myDadaMap.put(ConvertUtil.convertToString(tabItem.get("relationdata")), subList);
                }
            }
            // 当前节点不为空时添加附件信息
            if (queryById != null) {
                ICboAttachmentService cboAttachmentService = (CboAttachmentService) SpringUtil
                        .getBean("cboAttachmentService");
                List<String> fieldList = new ArrayList<>();
                fieldList.add("filetype");
                fieldList.add("filesize");
                fieldList.add("displayname");
                fieldList.add("sourcetype");
                fieldList.add("id");
                List<Map<String, Object>> attachList = cboAttachmentService
                        .queryMapFieldsByWhere("sourceid=" + ConvertUtil.convertToString(paraMap.get("id"))
                                + " and sourcetype='" + queryById.getSourcetype() + "'", fieldList);
                myDadaMap.put("attachmentList", attachList);
            }
            appPageService.getPageInfo(pageCode, myDadaMap);
            return ResponseResult.ok(myDadaMap);
        }
    }

    /**
     * 添加额外的数据项
     *
     * @param paraMap
     * @param mainListData
     */
    public void mainListExtraData(Map<String, Object> paraMap, Map<String, Object> mainListData) {
    }

    /**
     * @param exception
     * @description: 用以处理逻辑业务抛出的ServiceException 防止平台记录为异常 也防止手机端收到500错误后重复请求。
     * @author xinfushuo
     * @return ResposeResult success 为 false 的返回体
     * @date 2022/5/7
     * @modify
     */
    protected ResponseResult<Object> handleServiceException(ServiceException exception) {
        return ResponseResult.error(TapHttpStatus.HTTP_OK, TapHttpErrorCode.ERROR_MESSAGE, exception.getMessage());
    }

    /**
     * @Description: 下载合同模板并预览
     * @Author: mengmeng
     * @Date: 2021/9/16 14:42
     * @Version: 1.0
     */
    @PostMapping(value = "/previewDownLoad")
    public void download(@RequestBody Map<String, Object> paraMap, HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            paraMap = BaseUtil.decodeSecureMap(paraMap);
            Map<String, Object> resultMap = this.service.executeDownload(paraMap);
            // 设置文件名字(给要下载文件重命名);
            String fileName = ConvertUtil.convertToString(resultMap.get("attFileName"));
            response.setContentType("application/octet-stream");
//			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            InputStream inStream = BaseUtil.convertByteToStream((byte[]) resultMap.get("attInputStream"));
            OutputStream outStream = response.getOutputStream();
            byte[] bytes = new byte[2048];
            int len;
            while ((len = inStream.read(bytes)) != -1) {
                outStream.write(bytes, 0, len);
            }
            inStream.close();
        } catch (Exception e) {
            response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED, e.getMessage());
        }
    }
}
